.text
.section .rodata
.align 3
.LC1:
        .string "%d\t"
        .align  3
.LC2:
        .string "arr[%d][%d][%d] = %d \t"
        .align  3
.LC0:
        .word   1
        .word   2
        .word   3
        .word   4
        .word   5
        .word   6
        .word   7
        .word   8
        .word   9
        .word   10
        .word   11
        .word   12
        .word   11
        .word   12
        .word   13
        .word   14
        .word   15
        .word   16
        .word   17
        .word   18
        .word   19
        .word   110
        .word   111
        .word   112

.text
.globl main
.type main, @function
main:
    addi sp, sp, -144
    sd ra, 136(sp)
    sd s0, 128(sp)
    addi s0, sp, 128
    // 规划一下变量
    // arr：-112(s0)
    // p: -16(s0)
    // i: -8(s0)
    // 这里跟C源码稍微不一致，源码的size_t是8位，但我这里用的是int，是4位，不影响运行
    // j: -4(s0)
    // k: -116(s0)
    // -128 ~ -116留空
    lui a5, %hi(.LC0)
    addi a1, a5, %lo(.LC0)
    li a2, 96
    addi a0, s0, -112
    // 通过拷贝内存来实现数组初始化
    call memcpy

    addi a5, s0, -112
    sd a5, -16(s0) /* p */
    sw zero, -8(s0) /* i */
    j .FOR1COMPARE
.FOR1ENTER:
    lw a5, -8(s0) /* i */
    sext.w a5, a5
    li a4, 0
    ble a5, a4, .FOR1PRINT
    andi a5, a5, 3
    bne a5, zero, .FOR1PRINT
    li a0, 10
    call putchar

.FOR1PRINT:
    ld a5, -16(s0) /* p */
    lw a4, -8(s0) /* i */
    sext.w a4, a4
    slli a4, a4, 2
    add a5, a4, a5
    lw a1, (a5)
    lui a5, %hi(.LC1)
    addi a0, a5, %lo(.LC1)
    call printf

    lw a5, -8(s0) /* i */
    addiw a5, a5, 1
    sw a5, -8(s0) /* i */
.FOR1COMPARE:
    lw a5, -8(s0) /* i */
    sext.w a5, a5
    li a4, 24
    blt a5, a4, .FOR1ENTER

    li a0, 10
    call putchar

    sw zero, -8(s0) /* i */
    j .FOR2OUTCOMPARE
.FOR2OUTENTER:
    sw zero, -4(s0) /* j */
    j .FOR2MIDCOMPARE
.FOR2MIDENTER:
    sw zero, -116(s0) /*k */
    j .FOR2INNERCOMPARE
.FOR2INNERENTER:
    lw a5, -8(s0) /* i */
    sext.w a5, a5
    mv a4, a5
    slli a5, a5, 1
    add a5, a4, a5
    mv a4, a5
    lw a5, -4(s0) /* j */
    sext.w a5, a5
    add a5, a4, a5
    slli a5, a5, 2
    mv a4, a5
    lw a5, -116(s0) /*k */
    sext.w a5, a5
    add a5, a5, a4
    slli a5, a5, 2
    add a5, a5, s0
    lw a4, -112(a5)
    lw a1, -8(s0) /* i */
    lw a2, -4(s0) /* j */
    lw a3, -116(s0) /*k */
    lui a5, %hi(.LC2)
    addi a0, a5, %lo(.LC2)
    call printf

.FOR2INNERINCR:
    lw a5, -116(s0) /*k */
    addiw a5, a5, 1
    sw a5, -116(s0) /*k */
.FOR2INNERCOMPARE:
    lw a5, -116(s0) /*k */
    sext.w a5, a5
    li a4, 4
    blt a5, a4, .FOR2INNERENTER

    li a0, 10
    call putchar
// j++
.FOR2MIDINCR:
    lw a5, -4(s0) /* j */
    // 下面两句可以换成addiw a5, a5, 1
    sext.w a5, a5
    addi a5, a5, 1
    sw a5, -4(s0) /* j */
.FOR2MIDCOMPARE:
    lw a5, -4(s0) /* j */
    sext.w a5, a5
    li a4, 3
    blt a5, a4, .FOR2MIDENTER
.FOR2OUTINCR:
    lw a5, -8(s0) /* i */
    sext.w a5, a5
    addi a5, a5, 1
    sw a5, -8(s0) /* i */
.FOR2OUTCOMPARE:
    lw a5, -8(s0) /* i */
    sext.w a5, a5
    li a4, 2
    blt a5, a4, .FOR2OUTENTER

    ld ra, 136(sp)
    ld s0, 128(sp)
    addi sp, sp, 144
    jr ra